-
Notifications
You must be signed in to change notification settings - Fork 42
Fix key prop type #74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/React.res
Outdated
external jsx: (component<'props>, 'props) => element = "jsx" | ||
external jsxKeyed: (component<'props>, 'props, string) => element = "jsx" | ||
|
||
let jsx = (~key=?, component, props) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering whether this can be achieved directly with an external.
Btw where is the documentation that one can pass the key as third argument to the react jsx
function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
external jsxKeyed: (component<'props>, 'props, ~key: option<string>=?) => element = "jsx"
Like this? Shouldn't we have to move the labelled key argument position to first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that can't be done because it needs to be before mandatory arguments.
Unless one adds a fake additional mandatory argument of type unit perhaps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this work?
type was wrong_edited_to_fix_type_of_key
external jsx: (component<'props>, 'props, ~key: string=?, @ignore unit) => element = "jsx"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this work?
external jsx: (component<'props>, 'props, ~key: option<string>=?, @ignore unit) => element = "jsx"
I don't think it is working.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for cleanest generated output, one needs to expose 2 functions:
jsx
without a key argument, and jsxKeyed
with a mandatory 3rd argument of type option<string>
.
Then at call site the PPX would call jsx
when key
is not passed, and would call jsxKeyed
when key
is passed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, I couldn't find the doc about the third argument as key, but I found it from the source code. https://github.com/facebook/react/blob/8e2bde6f2751aa6335f3cef488c05c3ea08e074a/packages/react/src/jsx/ReactJSXElement.js#L210
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the key argument needs to be optional not option<string>
as mandatory. If it is option<string>
as mandatory, then users should use it.
<C key=Some("k") />
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the key argument needs to be optional not
option<string>
as mandatory. If it isoption<string>
as mandatory, then users should use it.<C key=Some("k") />
It does not have to be optional. The PPX can take care of passing the value in the appropriate way.
But it might be simpler to make it optional so the call PPX only needs to do one special thing: pass a final ()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for cleanest generated output, one needs to expose 2 functions:
jsx
without a key argument, andjsxKeyed
with a mandatory 3rd argument of typeoption<string>
. Then at call site the PPX would calljsx
whenkey
is not passed, and would calljsxKeyed
whenkey
is passed.
This would be easy fix, I'll fix the binding and make a PR for PPX.
rescript-lang/syntax#693 (comment) Maybe we need to revert the |
Exploring the opportunity to use cloneElement. Assuming I understood how this works https://reactjs.org/docs/react-api.html#cloneelement Instead of this: React.createElementWithKey(~key="k", V4CA.make, {}) one would generate this: React.cloneElement(React.createElement(V4CA.make, {}), {"key": "k"}) So one would rely on 2 pure bindings without any runtime in rescript-react. |
Good idea! |
That's certainly an advantage, but it will be even more inefficient than the Here is the implementation of |
I think we would only need to do make sure that the props object is copied in the <A {...props} key /> case. (In JS, Then we can use the Obj.magic(props)["key"] = key solution for all cases. |
For the jsx mode, that seems the way things will trend over time. And it makes sense to optimise the code generated in that case. In particular, it would be nice to introduce zero dependencies, so one can look at the generated code and understand it in isolation. |
The case where But yes, if we view this as "legacy JSX transform support", then that's probably ok, as we do not have the same issue with |
In this case, |
I agree you both. I'll revert the |
This reverts commit 2f48356.
I've fixed it rescript-lang/syntax#694 234798b |
CHANGELOG.md
Outdated
@@ -1,5 +1,10 @@ | |||
# Changelog | |||
|
|||
## 0.11.0-rc.3 | |||
|
|||
- Renamed `React.jsx(s)`, `ReactDOM.jsx(s)` to `React.jsx(s)NotKeyed`, `ReactDOM.jsx(s)NotKeyed`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for missing changelog and tests too often 😅
Updated b8fa0f3
This PR fixed #73